package cn.exrick.front.controller;

import cn.exrick.common.constant.CommonConstant;
import cn.exrick.common.pojo.Result;
import cn.exrick.common.utils.ResultUtil;
import cn.exrick.common.utils.ThreadPoolUtil;
import cn.exrick.manager.dto.front.OrderInfo;
import cn.exrick.manager.dto.front.PageOrder;
import cn.exrick.manager.pojo.TbMember;
import cn.exrick.manager.pojo.TbOrder;
import cn.exrick.manager.pojo.TbOrderItem;
import cn.exrick.manager.service.EmailTemplateService;
import cn.exrick.sso.service.CartService;
import cn.exrick.sso.service.MemberService;
import cn.exrick.sso.service.OrderService;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@RestController
@Api(description = "订单")
public class OrderController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private EmailTemplateService emailTemplateService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private CartService cartService;

    @Value("${app_id}")
    private String appId;

    @Value("${merchant_private_key}")
    private String privateKey;

    @Value("${alipay_public_key}")
    private String publicKey;

    @Value("${sign_type}")
    private String signType;

    @Value("${gatewayUrl}")
    private String gatewayUrl;

    @Value("${notify_url}")
    private String notifyUrl;

    @Value("${return_url}")
    private String returnUrl;

    private AlipayClient alipayClient;

    @PostConstruct
    private void inint(){
        alipayClient = new DefaultAlipayClient(gatewayUrl,appId, privateKey, "json", "utf-8", publicKey, signType);
    }



    @RequestMapping(value = "/order/orderList",method = RequestMethod.GET)
    @ApiOperation(value = "获得用户所有订单")
    public Result<PageOrder> getOrderList(HttpSession session,
                                          @RequestParam(defaultValue = "1") int page,
                                          @RequestParam(defaultValue = "5") int size){
        TbMember member = (TbMember) session.getAttribute(CommonConstant.USER_SESSION);
        PageOrder pageOrder=orderService.getOrderList(member.getId(), page, size);
        return new ResultUtil<PageOrder>().setData(pageOrder);
    }

    @RequestMapping(value = "/order/orderDetail",method = RequestMethod.GET)
    @ApiOperation(value = "通过id获取订单")
    public Result<TbOrder> getOrder(String orderId){

        TbOrder order=orderService.getOrder(orderId);
        return new ResultUtil<TbOrder>().setData(order);
    }

    @RequestMapping(value = "/order/addOrder",method = RequestMethod.POST)
    @ApiOperation(value = "创建订单")
    public Result<Object> addOrder(@RequestBody OrderInfo orderInfo, HttpSession session){
        TbMember member = (TbMember) session.getAttribute(CommonConstant.USER_SESSION);
        orderInfo.setUserId(String.valueOf(member.getId()));
        Result<Object> result = orderService.createOrder(orderInfo);
        if(!result.isSuccess()){
            return result;
        }
        //发送审批通知
        TbMember tbMember = memberService.getMemberById(Long.valueOf(orderInfo.getUserId()));
        if(tbMember != null && CommonConstant.MEMBER_TYPE_INNER.equals(tbMember.getType())){
            ThreadPoolUtil.getPool().execute(()-> emailTemplateService.sendOrderApprovalEmail((String) result.getResult(),0));
        }

        return result;
    }

    @RequestMapping(value = "/order/cancelOrder",method = RequestMethod.POST)
    @ApiOperation(value = "取消订单")
    public Result<Object> cancelOrder(String orderId){

        int result=orderService.cancelOrder(orderId);
        return new ResultUtil<Object>().setData(result);
    }

    @RequestMapping(value = "/order/delOrder",method = RequestMethod.POST)
    @ApiOperation(value = "删除订单")
    public Result<Object> delOrder(String orderId){
        orderService.delOrder(orderId);
        return new ResultUtil<Object>().setData(null);
    }

    @RequestMapping(value = "/order/detail",method = RequestMethod.POST)
    @ApiOperation(value = "订单详情")
    public Result<TbOrder> orderDetail(String orderId){
        TbOrder order = orderService.getOrder(orderId);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");
        order.setCreateTimeStr(dateFormat.format(order.getCreateTime()));
        if(order.getPayTime() != null){
            order.setPayTimeStr(dateFormat.format(order.getPayTime()));
        }

        if(order.getFinishTime() != null){
            order.setFinishTimeStr(dateFormat.format(order.getFinishTime()));
        }
        return new ResultUtil<TbOrder>().setData(order);
    }

    @RequestMapping(value = "/order/reBuy",method = RequestMethod.POST)
    @ApiOperation(value = "重新购买")
    public Result<Object> reBuy(String orderId){
        TbOrder order = orderService.getOrder(orderId);
        List<TbOrderItem> orderItemList = order.getOrderItemList();
        for(TbOrderItem orderItem : orderItemList){
            cartService.addCart(order.getUserId(),Long.valueOf(orderItem.getItemId()),orderItem.getNum());
        }
        return new ResultUtil<Object>().setData(null);
    }

    @RequestMapping(value = "/order/payOrder",method = RequestMethod.GET)
    @ApiOperation(value = "支付订单")
    public void payOrder(String orderId, HttpServletResponse response){
        TbOrder order = orderService.getOrder(orderId);
        //初始化
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request
        alipayRequest.setReturnUrl(returnUrl);
        alipayRequest.setNotifyUrl(notifyUrl);
        AlipayTradeWapPayModel payModel = new AlipayTradeWapPayModel();
        //商户订单号，必填
        payModel.setOutTradeNo(order.getOrderId().toString());
        //付款金额，必填
        payModel.setTotalAmount(order.getPayment().toString());
        //产品码，必填
        payModel.setProductCode("FAST_INSTANT_TRADE_PAY");
        //订单名称，必填
        List<TbOrderItem> goodsList = order.getOrderItemList();
        String subject = "";
        for(TbOrderItem orderItem : goodsList){
            subject += orderItem.getTitle()+"，";
        }
        subject = subject.substring(0,subject.length()-1);
        payModel.setSubject(subject);
        //商品描述，可空
        payModel.setBody(subject);
        alipayRequest.setBizModel(payModel);
        String form="";
        try {
            form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        response.setContentType("text/html;charset=utf-8");
        try {
            response.getWriter().write(form);//直接将完整的表单html输出到页面
            response.getWriter().flush();
            response.getWriter().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping(value = "/order/notify",method = RequestMethod.POST)
    public String notify(HttpServletRequest request) throws Exception {
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name =  iter.next();
            String[] values =  requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
//            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, publicKey, "utf-8", signType); //调用SDK验证签名

        if(signVerified) {//验证成功
            //商户订单号
            String orderId = request.getParameter("out_trade_no");
            //支付宝交易号
            String tradeNo = request.getParameter("trade_no");
            //交易状态
            String tradeStatus = request.getParameter("trade_status");
            if (tradeStatus.equals("TRADE_SUCCESS")){
                orderService.payOrder(orderId,tradeNo);
                //发送取货通知
                ThreadPoolUtil.getPool().execute(()-> emailTemplateService.sendPickupEmail(orderId));
            }

        }else {//验证失败
           return "fail";
        }
        return "success";
    }

    /**
     * 支付完成后跳转页面
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/order/return",method = RequestMethod.GET)
    public void orderReturn(HttpServletRequest request,HttpServletResponse response) throws Exception {
        Map<String,String> params = new HashMap<>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name =  iter.next();
            String[] values =  requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
//            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, publicKey, "utf-8", signType); //调用SDK验证签名

        if(signVerified) {//验证成功
            response.sendRedirect("/personalCenter");
        }else {//验证失败
            response.sendRedirect("");
        }
    }

}
